import './DndKit.scss'
import { v4 } from 'uuid'
import { useState } from 'react'
import { Input, Button, Radio, Space, Select, Popconfirm, Checkbox } from "antd"
import { HolderOutlined, DeleteOutlined } from '@ant-design/icons'
import { CSS } from '@dnd-kit/utilities'
import { DndContext, closestCenter, KeyboardSensor, PointerSensor, useSensor, useSensors } from '@dnd-kit/core'
import { useSortable, arrayMove, SortableContext, sortableKeyboardCoordinates, verticalListSortingStrategy } from '@dnd-kit/sortable'

import { modelStore } from '../Config/zustand'
import { MappingData } from '../Config/MappingData'

import { removeTreeByKey } from '.'



// Todo 字段设置 渲染
const MenuFiledTempItem = ({ id, item, FieldEvent }) => {
    const colorMapping = { 0: '#ffccc7', 1: '#e6f4ff', 2: '#f6ffed' }
    const { updateModel } = modelStore()
    const { dataField, caption, status } = item

    const [value, setValue] = useState(caption)

    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id })
    const style = { transform: CSS.Transform.toString(transform), transition, background: colorMapping[status] }
    const onInputChange = (e) => {
        item.caption = e
        FieldEvent.emit({ type: 'onModify', data: item })
        setValue(e)
    }

    const onDetailed = () => {
        updateModel({ title: `${dataField} 字段设置`, type: 'SetAdminRouterField', width: 640, data: { item, FieldEvent } })
    }

    const onDelete = () => {
        FieldEvent.emit({ type: 'onDelete', data: item })
    }

    return (
        <div className='MenuFiledTempItem' ref={setNodeRef} style={style} {...attributes} >
            <HolderOutlined {...listeners} />
            <div className='field'>
                <div className='item'>
                    <div>{dataField}</div>
                    <Input value={value} onChange={e => onInputChange(e.target.value)} />
                </div>
            </div>
            <div className='options'>
                {status === 0 ?
                    <Button type='link' danger onClick={onDelete}>删除字段</Button> :
                    <Button type='link' onClick={onDetailed}>详细设置</Button>
                }
            </div>
        </div>
    )
}

export const MenuFiledTemp = ({ data, FieldEvent }) => {
    const [FidedData, setFidedData] = useState(data)
    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
    )
    const handleDragEnd = (event) => {
        const { active, over } = event
        if (active.id !== over.id) {
            const oldIndex = FidedData.findIndex(v => v.id === active.id)
            const newIndex = FidedData.findIndex(v => v.id === over.id)
            const data = arrayMove(FidedData, oldIndex, newIndex)
            FieldEvent.emit({ type: 'onUpdate', data })
            setFidedData(data)
        }
    }

    FieldEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'onModify') {
            const newData = FidedData.map(item => (item.id === data.id ? data : item))
            FieldEvent.emit({ type: 'onUpdate', data: newData })
            setFidedData(newData)
        }
        if (type === 'onDelete') {
            const newData = FidedData.filter(v => v.dataField !== data.dataField)
            FieldEvent.emit({ type: 'onUpdate', data: newData })
            setFidedData(newData)
        }
    })

    return (
        <div className='MenuFiledTemp'>
            <DndContext handlesensors={sensors} onDragEnd={handleDragEnd} collisionDetection={closestCenter}>
                <SortableContext items={FidedData} strategy={verticalListSortingStrategy}>
                    {FidedData.map(item => <MenuFiledTempItem key={item.id} id={item.id} item={item} FieldEvent={FieldEvent} />)}
                </SortableContext>
            </DndContext>
        </div>
    )
}


// Todo 字段操作设置
const SetOptionsFieldItem = ({ id, item, FieldEvent }) => {
    const { updateModel } = modelStore()
    const { dataField, caption, visible, rules } = item

    const [value, setValue] = useState(caption)
    const [status, setStatus] = useState(visible)
    const [checked, setChecked] = useState(rules)


    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id })
    const style = { transform: CSS.Transform.toString(transform), transition, background: '#e6f4ff' }
    const onInputChange = (e) => {
        item.caption = e
        FieldEvent.emit({ type: 'onModify', data: item })
        setValue(e)
    }

    const onRadioChange = e => {
        item.visible = e
        FieldEvent.emit({ type: 'onModify', data: item })
        setStatus(e)
    }

    const onChange = (e) => {
        item.rules = e
        FieldEvent.emit({ type: 'onModify', data: item })
        setChecked(e)
    }

    return (
        <div className='MenuFiledTempItem' ref={setNodeRef} style={style} {...attributes} >
            <HolderOutlined {...listeners} />
            <div className='field'>
                <div className='item'>
                    <div>{dataField}</div>
                    <Input value={value} onChange={e => onInputChange(e.target.value)} />
                </div>
            </div>
            <div className='options'>
                <Radio.Group value={status} buttonStyle="solid" onChange={e => onRadioChange(e.target.value)}>
                    <Radio.Button value={true}>显示</Radio.Button>
                    <Radio.Button value={false}>隐藏</Radio.Button>
                </Radio.Group>
                <Checkbox checked={checked} onChange={e => onChange(e.target.checked)}>必填</Checkbox>
            </div>
        </div>
    )
}
export const SetOptionsField = ({ data, FieldEvent }) => {
    const [FidedData, setFidedData] = useState(data)
    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
    )
    const handleDragEnd = (event) => {
        const { active, over } = event
        if (active.id !== over.id) {
            const oldIndex = FidedData.findIndex(v => v.id === active.id)
            const newIndex = FidedData.findIndex(v => v.id === over.id)
            const data = arrayMove(FidedData, oldIndex, newIndex)
            FieldEvent.emit({ type: 'onUpdateField', data })
            setFidedData(data)
        }
    }

    FieldEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'onModify') {
            const newData = FidedData.map(item => (item.id === data.id ? data : item))
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
    })

    return (
        <div className='SetOptionsField'>
            <DndContext handlesensors={sensors} onDragEnd={handleDragEnd} collisionDetection={closestCenter}>
                <SortableContext items={FidedData} strategy={verticalListSortingStrategy}>
                    {FidedData.map(item => <SetOptionsFieldItem key={item.id} id={item.id} item={item} FieldEvent={FieldEvent} />)}
                </SortableContext>
            </DndContext>
        </div>
    )
}

// Todo 搜索字段设置
const SetSearchFieldItem = ({ id, item, FieldEvent }) => {
    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id })
    const style = { transform: CSS.Transform.toString(transform), transition, background: '#e6f4ff' }
    const [Data, setData] = useState(item)
    const onChange = (e, key) => {
        const data = { ...Data, [key]: e }
        setData(data)
        FieldEvent.emit({ type: 'onModify', data: data })
    }

    const onDelete = () => {
        FieldEvent.emit({ type: 'onDelete', data: id })
    }

    return (
        <div className='SetSearchFieldItem' ref={setNodeRef} style={style} {...attributes} >
            <HolderOutlined {...listeners} />
            <div className='field'>
                <Input addonBefore="字段名称" value={Data.value} onChange={e => onChange(e.target.value, 'value')} />
                <Radio.Group value={Data.isSystem} buttonStyle="solid" onChange={e => onChange(e.target.value, 'isSystem')}>
                    <Radio.Button value={true}>匹配字段</Radio.Button>
                    <Radio.Button value={false}>单独类型</Radio.Button>
                </Radio.Group>
                <Input addonBefore="中文映射" value={Data.label} onChange={e => onChange(e.target.value, 'label')} />
                {!Data.isSystem &&
                    <Space.Compact>
                        <Button>单独类型</Button>
                        <Select
                            value={Data.valueType}
                            options={MappingData.Form__TypeList}
                            style={{ width: '100%' }}
                            onChange={e => onChange(e, 'valueType')}
                        />
                    </Space.Compact>
                }
            </div>
            <Popconfirm
                title="删除预警!"
                description="是否删除当前搜索条件?"
                onConfirm={onDelete}
                okText="删除"
                cancelText="取消"
            >
                <Button shape="circle" danger icon={<DeleteOutlined />} ghost />
            </Popconfirm>
        </div>
    )
}
export const SetSearchField = ({ data, FieldEvent }) => {
    const [FidedData, setFidedData] = useState(data)
    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
    )
    const handleDragEnd = (event) => {
        const { active, over } = event
        if (active.id !== over.id) {
            const oldIndex = FidedData.findIndex(v => v.id === active.id)
            const newIndex = FidedData.findIndex(v => v.id === over.id)
            const data = arrayMove(FidedData, oldIndex, newIndex)
            FieldEvent.emit({ type: 'onUpdateField', data })
            setFidedData(data)
        }
    }

    FieldEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'onModify') {
            const newData = FidedData.map(item => (item.id === data.id ? data : item))
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
        if (type === 'onAddField') {
            const newData = [...FidedData, { id: v4(), ...data }]
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
        if (type === 'onDelete') {
            const newData = removeTreeByKey(FidedData, data, 'id')
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
    })

    return (
        <div className='SetOptionsField'>
            <DndContext handlesensors={sensors} onDragEnd={handleDragEnd} collisionDetection={closestCenter}>
                <SortableContext items={FidedData} strategy={verticalListSortingStrategy}>
                    {FidedData.map(item => <SetSearchFieldItem key={item.id} id={item.id} item={item} FieldEvent={FieldEvent} />)}
                </SortableContext>
            </DndContext>
        </div>
    )
}

// Todo 排序字段设置
const SetSortFieldItem = ({ id, item, FieldEvent }) => {
    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id })
    const style = { transform: CSS.Transform.toString(transform), transition, background: '#e6f4ff' }
    const [Data, setData] = useState(item)
    const onChange = (e, key) => {
        const data = { ...Data, [key]: e }
        setData(data)
        FieldEvent.emit({ type: 'onModify', data: data })
    }

    const onDelete = () => {
        FieldEvent.emit({ type: 'onDelete', data: id })
    }

    return (
        <div className='SetSearchFieldItem' ref={setNodeRef} style={style} {...attributes} >
            <HolderOutlined {...listeners} />
            <div className='field'>
                <Input addonBefore="字段名称" value={Data.value} onChange={e => onChange(e.target.value, 'value')} />
                <Radio.Group value={Data.sort} buttonStyle="solid" onChange={e => onChange(e.target.value, 'sort')}>
                    <Radio.Button value='none'>无序</Radio.Button>
                    <Radio.Button value='asc'>正序</Radio.Button>
                    <Radio.Button value='desc'>倒序</Radio.Button>
                </Radio.Group>
                <Input addonBefore="中文映射" value={Data.label} onChange={e => onChange(e.target.value, 'label')} />
            </div>
            <Popconfirm
                title="删除预警!"
                description="是否删除当前搜索条件?"
                onConfirm={onDelete}
                okText="删除"
                cancelText="取消"
            >
                <Button shape="circle" danger icon={<DeleteOutlined />} ghost />
            </Popconfirm>
        </div>
    )
}
export const SetSortField = ({ data, FieldEvent }) => {
    const [FidedData, setFidedData] = useState(data)
    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
    )
    const handleDragEnd = (event) => {
        const { active, over } = event
        if (active.id !== over.id) {
            const oldIndex = FidedData.findIndex(v => v.id === active.id)
            const newIndex = FidedData.findIndex(v => v.id === over.id)
            const data = arrayMove(FidedData, oldIndex, newIndex)
            FieldEvent.emit({ type: 'onUpdateField', data })
            setFidedData(data)
        }
    }

    FieldEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'onModify') {
            const newData = FidedData.map(item => (item.id === data.id ? data : item))
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
        if (type === 'onAddField') {
            const newData = [...FidedData, { id: v4(), ...data }]
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
        if (type === 'onDelete') {
            const newData = removeTreeByKey(FidedData, data, 'id')
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
    })

    return (
        <div className='SetOptionsField'>
            <DndContext handlesensors={sensors} onDragEnd={handleDragEnd} collisionDetection={closestCenter}>
                <SortableContext items={FidedData} strategy={verticalListSortingStrategy}>
                    {FidedData.map(item => <SetSortFieldItem key={item.id} id={item.id} item={item} FieldEvent={FieldEvent} />)}
                </SortableContext>
            </DndContext>
        </div>
    )
}

// Todo 获取排序字段
const GetSortFieldItem = ({ id, item, FieldEvent }) => {
    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id })
    const style = { transform: CSS.Transform.toString(transform), transition, background: '#e6f4ff' }
    const [Data, setData] = useState(item)
    const onChange = (e, key) => {
        const data = { ...Data, [key]: e }
        setData(data)
        FieldEvent.emit({ type: 'onModify', data: data })
    }

    const onDelete = () => {
        FieldEvent.emit({ type: 'onDelete', data: id })
    }

    return (
        <div className='SetSearchFieldItem' ref={setNodeRef} style={style} {...attributes} >
            <HolderOutlined {...listeners} />
            <div className='field'>
                <div>{Data.label}</div>
                <Radio.Group value={Data.sort} buttonStyle="solid" onChange={e => onChange(e.target.value, 'sort')}>
                    <Radio.Button value='none'>无序</Radio.Button>
                    <Radio.Button value='asc'>正序</Radio.Button>
                    <Radio.Button value='desc'>倒序</Radio.Button>
                </Radio.Group>
            </div>
        </div>
    )
}
export const GetSortField = ({ data, FieldEvent }) => {
    const [FidedData, setFidedData] = useState(data)
    const sensors = useSensors(
        useSensor(PointerSensor),
        useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
    )
    const handleDragEnd = (event) => {
        const { active, over } = event
        if (active.id !== over.id) {
            const oldIndex = FidedData.findIndex(v => v.id === active.id)
            const newIndex = FidedData.findIndex(v => v.id === over.id)
            const data = arrayMove(FidedData, oldIndex, newIndex)
            FieldEvent.emit({ type: 'onUpdateField', data })
            setFidedData(data)
        }
    }

    FieldEvent.useSubscription(val => {
        const { type, data } = val
        if (type === 'onModify') {
            const newData = FidedData.map(item => (item.id === data.id ? data : item))
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
        if (type === 'onAddField') {
            const newData = [...FidedData, { id: v4(), ...data }]
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
        if (type === 'onDelete') {
            const newData = removeTreeByKey(FidedData, data, 'id')
            FieldEvent.emit({ type: 'onUpdateField', data: newData })
            setFidedData(newData)
        }
    })

    return (
        <div className='SetOptionsField'>
            <DndContext handlesensors={sensors} onDragEnd={handleDragEnd} collisionDetection={closestCenter}>
                <SortableContext items={FidedData} strategy={verticalListSortingStrategy}>
                    {FidedData.map(item => <GetSortFieldItem key={item.id} id={item.id} item={item} FieldEvent={FieldEvent} />)}
                </SortableContext>
            </DndContext>
        </div>
    )
}

